import json
import logging

from django.db import IntegrityError
from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.utils import timezone
from django.utils.baseconv import base64
from django.utils.decorators import method_decorator
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from common.custom_exceptions import UserException, decorator_exception
from common.models import MusicInfo
from common.tools.wechat_tools import getsign
from common.views import BaseListView, AuthTemplateView, AuthShopAPIView, get_obj, AuthMobileTemplateView, \
    get_object_or_userexcept
from wehelp.models import KanjiaInfo, KanJiaUserMaster, KanJiaUserMem
from wehelp.serializers import KanjiaInfoSerializer, KanMasterSerializer, KanMemSerializer

logger = logging.getLogger('qixiaobao')


class KanjiaInfoListView(BaseListView):
    """活动列表"""
    template_name = 'wehelp/list.html'
    model = KanjiaInfo
    context_object_name = "kanjia_list"

    def get_queryset(self):
        self.keyword = self.request.GET.get('keyword', '')
        # 测试错误邮件
        # raise Exception('测似错误邮件')
        if self.keyword:
            self.keyword = self.keyword.replace('-', '+').replace('_', '/')
            self.keyword = (base64.decodestring(self.keyword)).strip()
        return KanjiaInfo.objects.filter(title__contains=self.keyword, shop=self.shop, status=KanjiaInfo.STATUS_VALID)

    def get_context_data(self, **kwargs):
        kwargs['secure'] = self.request.is_secure()
        return super(KanjiaInfoListView, self).get_context_data(**kwargs)


class KanjiaInfoAddView(AuthTemplateView):
    """新建活动"""
    template_name = 'wehelp/add.html'
    serializer_class = KanjiaInfoSerializer

    def get_context_data(self, **kwargs):
        kwargs['secure'] = self.request.is_secure()
        kwargs['musics'] = MusicInfo.objects.filter(status=MusicInfo.STATUS_VALID)
        return super(KanjiaInfoAddView, self).get_context_data(**kwargs)

    def post(self, request, *args, **kwargs):
        serializer = KanjiaInfoSerializer(data=request.POST)
        if serializer.is_valid():
            serializer.save(shop_id=kwargs['shop_id'], status=KanjiaInfo.STATUS_VALID)
            return JsonResponse({'status': 0, 'detail': 'success'})
        else:
            return JsonResponse({'status': 1, 'detail': '活动添加失败！', 'errors': serializer.errors})


class KanjiaInfoEditView(AuthTemplateView):
    """编辑活动"""
    template_name = 'wehelp/edit.html'
    serializer_class = KanjiaInfoSerializer

    def get_context_data(self, **kwargs):
        kwargs['secure'] = self.request.is_secure()
        kwargs['kanjia'] = get_obj(KanjiaInfo, id=self.request.GET.get('id'))
        kwargs['musics'] = MusicInfo.objects.filter(status=MusicInfo.STATUS_VALID)
        return super(KanjiaInfoEditView, self).get_context_data(**kwargs)

    def post(self, request, *args, **kwargs):
        kanjia = get_obj(KanjiaInfo, id=request.POST.get('id'))
        serializer = KanjiaInfoSerializer(kanjia, data=request.POST)
        if serializer.is_valid():
            serializer.save(status=KanjiaInfo.STATUS_VALID)
            return JsonResponse({'status': 0, 'detail': 'success'})
        else:
            return JsonResponse({'status': 1, 'detail': serializer.errors, 'errors': serializer.errors})


class KanjiaInfoShelveView(AuthShopAPIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'title', 'id'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})
        kanjia = get_obj(KanjiaInfo, id=request.data.get('id'), status=KanjiaInfo.STATUS_VALID)
        if not kanjia:
            return Response({'status': 1, 'detail': '活动不存在！'})
        kanjia.shelve = not kanjia.shelve
        kanjia.save()
        return Response({'status': 0, 'detail': 'success'})


class KanjiaInfoDeleteView(AuthShopAPIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        """
        活动删除API
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        if not {'items'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})
        id_list = request.data.get("items").split(',')
        kanjia_list = KanjiaInfo.objects.filter(status=KanjiaInfo.STATUS_VALID, id__in=id_list)
        if not kanjia_list:
            return Response({'status': 1, 'detail': '活动列表不存在！'})
        for kanjia in kanjia_list:
            kanjia.status = KanjiaInfo.STATUS_INVALID
            kanjia.save()
        return Response({'status': 0, 'detail': 'success'})


class KanInfoJoinView(AuthMobileTemplateView):
    template_name = 'wehelp/join.html'

    def get_context_data(self, **kwargs):
        kwargs['kanjia'] = self.kanjia
        kwargs['state'] = self.request.GET.get('state', '')
        kwargs['join_list'] = KanJiaUserMaster.objects.filter(info=self.kanjia, status=KanJiaUserMaster.STATUS_VALID)[
                              :6]
        kwargs['artical_color'] = '#e20e35'  # 测试主题
        return super(KanInfoJoinView, self).get_context_data(**kwargs)

    def get(self, request, *args, **kwargs):
        self.kanjia = get_obj(KanjiaInfo, id=kwargs['product_id'])
        if not self.kanjia:
            return render(request, 'mobile/message.html', {'message': '活动不存在，请退出重试！'})
        if not self.kanjia.shelve:
            return render(request, 'mobile/message.html', {'message': '活动未上架！'})
        joiner = get_obj(KanJiaUserMaster, user=self.request.user, info=self.kanjia,
                         status=KanJiaUserMaster.STATUS_VALID)
        # 判断如果已经报名自动跳转砍价页
        if joiner:
            # 跳转砍价页
            url = '%s?shop=%s' % (reverse('wehelp:help', args=[joiner.id]), self.shop.id)
            return HttpResponseRedirect(url)

        return super(KanInfoJoinView, self).get(self, request, *args, **kwargs)

    @method_decorator(decorator_exception)
    def post(self, request, *args, **kwargs):
        kan_info = get_obj(
            KanjiaInfo,
            id=self.kwargs.get('product_id'),
            status=KanjiaInfo.STATUS_VALID
        )
        if not kan_info.shelve:
            raise UserException(u'活动未上架')
        # 判断活动时间
        now = timezone.now()
        if kan_info.start_time > now:
            raise UserException(u'活动还未开始，请耐心等待')
        elif kan_info.end_time < now:
            raise UserException(u'活动已结束')
        serializer = KanMasterSerializer(data=request.POST)
        kan_master = KanJiaUserMaster.objects.filter(user=request.user, info=kan_info,
                                                     status=KanJiaUserMaster.STATUS_VALID).first()
        if kan_master:
            ret_serializer = KanMasterSerializer(kan_master)
            return JsonResponse({'status': 0, 'detail': ret_serializer.data})
        if serializer.is_valid():
            phone = request.POST.get('phone', '').strip()
            # 判断该手机号是否已经参加过活动
            if KanJiaUserMaster.objects.filter(info=kan_info, phone=phone,
                                               status=KanJiaUserMaster.STATUS_VALID).exists():
                raise UserException(u'该手机号码已经报过名了')
            if phone:
                request.user.phone = phone
                request.user.save()
            try:
                kan_master = KanJiaUserMaster()

                kan_master.name = request.POST.get('name', '')
                kan_master.phone = request.POST.get('phone', '')
                kan_master.status = KanJiaUserMaster.STATUS_VALID
                kan_master.user = request.user
                kan_master.info = kan_info
                kan_master.real_price = kan_info.price_original
                kan_master.save()

            except IntegrityError:
                kan_master = KanJiaUserMaster.objects.filter(user=request.user, info=kan_info,
                                                             status=KanJiaUserMaster.STATUS_VALID).first()
            ret_serializer = KanMasterSerializer(kan_master)

            return JsonResponse({'status': 0, 'detail': ret_serializer.data})
        return JsonResponse({'status': 2, 'detail': serializer.errors})


class KanjiaInfoMasterView(AuthMobileTemplateView):
    template_name = 'wehelp/help_kan.html'

    def dispatch(self, request, *args, **kwargs):
        return super(KanjiaInfoMasterView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        product = self.kan_master.info
        kwargs['kan_master'] = self.kan_master
        kwargs['kanjia'] = product
        kwargs['inventory'] = product.inventory
        kwargs['is_self'] = self.kan_master.user == self.request.user
        kwargs['should_pay'] = self.kan_master.real_price == self.kan_master.info.price_discount
        if kwargs['is_self'] and kwargs['should_pay'] and self.kan_master.order:
            kwargs['has_pay'] = self.kan_master.order.state in [2, 3, 4]
        # 判断当前用户是否已经报名
        kwargs['has_join'] = KanJiaUserMaster.objects.filter(user=self.request.user, info=self.kan_master.info,
                                                             status=KanJiaUserMaster.STATUS_VALID).exists()
        kwargs['helper_list'] = KanJiaUserMem.objects.filter(master=self.kan_master, status=KanJiaUserMem.STATUS_VALID)[
                                :6]
        kwargs['state'] = self.request.GET.get('state', '')
        if 'MicroMessenger' in self.request.META.get('HTTP_USER_AGENT', ''):
            kwargs['sign'] = getsign(self.request, product.shop.id, True)
        return super(KanjiaInfoMasterView, self).get_context_data(**kwargs)

    @method_decorator(decorator_exception)
    def get(self, request, *args, **kwargs):
        if request.META['HTTP_HOST'] not in ['qxb.dongpouu.com']:
            if 'MicroMessenger' not in self.request.META.get('HTTP_USER_AGENT', ''):
                return render(request, 'mobile/message.html', {'message': '请在微信中打开该活动链接'})
        try:
            self.kan_master = KanJiaUserMaster.objects.select_related('info').get(
                id=self.kwargs.get('master_id'))  # 通过类似join的方式一次查询出相关活动信息，减少一次数据库查询。
        except KanJiaUserMaster.DoesNotExist:
            raise UserException('{}不存在'.format(KanJiaUserMaster._meta.verbose_name))
        if not self.kan_master.info.status == KanjiaInfo.STATUS_VALID:
            raise UserException(u'该活动不存在')
        if not self.kan_master.info.shelve:
            raise UserException(u'活动未上架')
        if not self.kan_master.status == KanJiaUserMaster.STATUS_VALID:
            state = request.GET.get('state', '')
            url = self.kan_master.info.get_absolute_url()
            if state:
                url += '&state=' + state
            return HttpResponseRedirect(url)
        return super(KanjiaInfoMasterView, self).get(request, *args, **kwargs)

    @method_decorator(decorator_exception)
    def post(self, request, *args, **kwargs):
        master = get_object_or_userexcept(
            KanJiaUserMaster,
            id=self.kwargs.get('master_id'),
            status=KanJiaUserMaster.STATUS_VALID,
            info__status=KanjiaInfo.STATUS_VALID
        )
        if not master.info.shelve:
            raise UserException(u'活动未上架')

        if not master.info.has_start():
            raise UserException(u'活动还未开始，请耐心等待')
        elif master.info.has_end():
            raise UserException(u'活动已结束')

        if not request.user == master.user and master.master_set.filter(status=KanJiaUserMem.STATUS_VALID,
                                                                        user=request.user).exists():
            raise UserException(u'已经帮好友减过价了')

        if request.user == master.user:
            master_mem = master.master_set.filter(status=KanJiaUserMem.STATUS_VALID, user=request.user).order_by(
                '-create_time').first()
            if master_mem and not master_mem.master_can_serve_for_self():
                raise UserException(u'距离上次减价时间不足{}分钟，请稍后再试'.format(master_mem.master.info.sub_time))

        if master.real_price == master.info.price_discount:
            raise UserException(u'已减至底价')

        kan_mem = KanJiaUserMem.objects.create(user=request.user,
                                               master=master,
                                               sub_price=master.get_random_price(),
                                               status=KanJiaUserMem.STATUS_VALID)
        master.set_price_cache()
        # 设置数据统计
        ret_serializer = KanMemSerializer(kan_mem)
        return JsonResponse({'status': 0, 'detail': ret_serializer.data})


class MobileListView(AuthMobileTemplateView):
    template_name = 'wehelp/mobile_kan_list.html'

    def dispatch(self, request, *args, **kwargs):
        return super(MobileListView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        kwargs['state'] = self.request.GET.get('state', '')
        kwargs['kanjia_list'] = KanjiaInfo.objects.filter(status=KanjiaInfo.STATUS_VALID, shelve=True, shop=self.shop)
        if 'MicroMessenger' in self.request.META.get('HTTP_USER_AGENT', ''):
            kwargs['sign'] = getsign(self.request, self.shop.id, True)
        return super(MobileListView, self).get_context_data(**kwargs)


class KanjiaOrderListView(BaseListView):
    """砍价订单列表"""
    template_name = 'wehelp/order_list.html'
    model = KanjiaInfo
    context_object_name = "master_list"

    def get_queryset(self):
        self.keyword = self.request.GET.get('keyword', '')
        # 测试错误邮件
        # raise Exception('测似错误邮件')
        if self.keyword:
            self.keyword = self.keyword.replace('-', '+').replace('_', '/')
            self.keyword = (base64.decodestring(self.keyword)).strip()
        return KanJiaUserMaster.objects.filter(name__contains=self.keyword, info__shop=self.shop,
                                               status=KanJiaUserMaster.STATUS_VALID)

    def get_context_data(self, **kwargs):
        kwargs['secure'] = self.request.is_secure()
        return super(KanjiaOrderListView, self).get_context_data(**kwargs)
